package org.jsbd.boss.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Random;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.jsbd.boss.action.ScriptController;
import org.jsbd.boss.common.DataGridModel;
import org.jsbd.boss.common.redis.RedisClient;
import org.jsbd.boss.dao.IScriptDAO;
import org.jsbd.boss.domian.channel.ChannelScriptItem;
import org.jsbd.boss.domian.channel.ChannelScriptRepo;
import org.jsbd.boss.domian.channel.ChannelScriptRepoMark;
import org.jsbd.boss.domian.channel.FileUploadVo;
import org.jsbd.boss.service.FileManager;
import org.jsbd.boss.service.IScriptService;
import org.jsbd.boss.util.CacheKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

@Service("scriptService")
public class ScriptServiceImpl implements IScriptService {

	public static final Logger LOGGER = LoggerFactory.getLogger(ScriptServiceImpl.class);
	
	@Resource
	private IScriptDAO scriptServiceDao;
	@Resource
	private FileManager fileManager;
	@Resource
	private RedisClient redisClient;
	
	@Override
	public Map<String, Object> getScriptRepoListJson(DataGridModel page, ChannelScriptRepo channelScriptRepo) {
		return scriptServiceDao.selectScriptRepoListJson(page, channelScriptRepo);
	}

	@Override
	public void saveChannelScriptRepo(ChannelScriptRepo channelScriptRepo) {
		scriptServiceDao.insertChannelScriptRepo(channelScriptRepo);
	}

	@Override
	public ChannelScriptRepo getScriptRepoByName(String name) {
		return scriptServiceDao.selectScriptRepoByName(name);
	}

	@Override
	public ChannelScriptRepo getScriptRepoById(Long id) {
		return scriptServiceDao.selectScriptRepoById(id);
	}

	@Override
	public void editChannelScriptRepo(ChannelScriptRepo channelScriptRepo) {
		scriptServiceDao.updateChannelScriptRepo(channelScriptRepo);
	}

	@Override
	public List<ChannelScriptRepoMark> getMarksByRepoId(Long id) {
		return scriptServiceDao.selectMarksByRepoId(id);
	}

	@Transactional("transactionManagerCrack")
	@Override
	public void deleteMarksByRepoId(Long repoId) {
		scriptServiceDao.deleteMarksByRepoId(repoId);
	}

	@Transactional("transactionManagerCrack")
	@Override
	public void addMark(List<ChannelScriptRepoMark> list) {
		scriptServiceDao.insertMark(list);
	}

	
	@Override
	public Map<String, Object> getScriptListJson(DataGridModel page, ChannelScriptItem channelScriptItem) {
		return scriptServiceDao.selectScriptListJson(page, channelScriptItem);
	}

	@Override
	public List<ChannelScriptRepo> getScriptRepoByEnable(Integer isEnable) {
		return scriptServiceDao.selectScriptRepoByEnable(isEnable);
	}

	@Override
	public void saveChannelScriptItem(ChannelScriptItem channelScriptItem, MultipartFile file) {
		FileUploadVo fileVo = fileManager.uploadFile(file);
		List<ChannelScriptItem> list = new ArrayList<ChannelScriptItem>();
		String[] repoIds = channelScriptItem.getRepoIds();
		if (fileVo != null) {
			for (String str : repoIds) {
				ChannelScriptItem csi = new ChannelScriptItem();
				csi.setName(channelScriptItem.getName());
				csi.setType(channelScriptItem.getType());
				csi.setRepoId(Long.valueOf(str));
				csi.setFilePath( fileVo.getFilePath());
				csi.setIsEnable(1);
				list.add(csi);
			}
		} 
		
		scriptServiceDao.insertChannelScriptItem(list);
	}

	@Override
	public void abandonScript(String name) {
		scriptServiceDao.abandonScript(name);
	}

	@Override
	public String randomScript(String mark, Integer type) {
		List<String> filePaths = (List<String>) redisClient.hget(CacheKey.SCRIPT_MARK, mark + '_' + type);
		if (null == filePaths || filePaths.size() ==0) {
			return null;
		}
		
		Long repoId = 0l;
		if (type == 1) {
			repoId = (Long) redisClient.hget(CacheKey.SCRIPT_MARK_REPOID, mark);
			//去除已经执行完的
			ListIterator<String> fpIterator = filePaths.listIterator();  
			while(fpIterator.hasNext()) {
				String filePath = fpIterator.next();
				Integer num = (Integer) redisClient.hget(CacheKey.SCRIPT_NUM, filePath + "_" + mark + "_" + repoId);
				if (null == num || num <= 0) {
					fpIterator.remove();
				}
			}
		}
			
		if (filePaths.size() > 0) {
			// 根据size取随机数
			Random Random = new Random();  
			int rand = Random.nextInt(filePaths.size());  
			// 随机返回一个脚本路径
			String filePath = filePaths.get(rand);
			if (type == 1) {
				Integer num = (Integer) redisClient.hget(CacheKey.SCRIPT_NUM, filePath + "_" + mark + "_" + repoId);
				redisClient.hset(CacheKey.SCRIPT_NUM, filePath + "_" + mark + "_" + repoId, --num);
			}
			return filePath;
		}
		return null;
	}

	@Override
	public ChannelScriptItem getScriptItemByName(String name) {
		return scriptServiceDao.selectScriptItemByName(name);
	}

	@Override
	public ChannelScriptRepoMark getScriptRepo(String mark) {
		return scriptServiceDao.selectScriptRepo(mark);
	}

	@Override
	public List<String> getFilePathByRepoIdAndType(Long repoId, int type) {
		return scriptServiceDao.selectFilePathByRepoIdAndType(repoId, type);
	}

	@Override
	public List<ChannelScriptRepoMark> getAllMarks() {
		return scriptServiceDao.selectAllMarks();
	}

	@Override
	public void deleteByMark(String mark) {
		scriptServiceDao.deleteByMark(mark);
	}

	@Override
	public List<ChannelScriptItem> getChannelScriptItemByRepoid(Long repoId) {
		return scriptServiceDao.selectChannelScriptItemByRepoid(repoId);
	}

	@Override
	public void saveConfigScriptNum(ChannelScriptItem channelScriptItem) {
		scriptServiceDao.updateConfigScriptNum(channelScriptItem);
	}

	@Override
	public List<String> getFilePathByRepoId(Long repoId) {
		return scriptServiceDao.selectFilePathByRepoId(repoId);
	}

	
}
